package com.zb.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 日期工具类
 * @Author WEN
 * @Date 2023/9/21 0021
 **/
public class ZbDateUtil {
    public static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_FORMAT_Y_M_D_H_M = "yyyy-MM-dd HH:mm";

    /**
     * 计算两个时间差，并返回年、天、小时
     * @return
     */
    public static String getTimeLength(Date val1, Date val2) {
        String timeLong = "";
        if (null == val1 || null == val2) {
            return timeLong;
        }
        long time = val2.getTime() - val1.getTime();
        long year = time / (365 * 24 * 60 * 60  * 1000L); // 年
        long date = time % (365 * 24 * 60 * 60  * 1000L) / (24 * 60 * 60  * 1000L); // 天
        long hour = time % (365 * 24 * 60 * 60  * 1000L) % (24 * 60 * 60  * 1000L) / (60 * 60  * 1000L); // 时
        timeLong = year > 0? year + "年" : "";
        timeLong += date > 0? date + "天" : "";
        timeLong += hour > 0? hour + "小时" : hour == 0? "1小时内" : "";
        return timeLong;
    }

    /**
     * 计算两个时间差，并返回天数
     * @param val1
     * @param val2
     * @return 计算方式：val2 - val1
     */
    public static long getDays(Date val1, Date val2) {
        long day = 0;
        if (null == val1 || null == val2) {
            return day;
        }
        Date v1 = dateToDateFormat(val1);
        if (null == v1) {
            return 0;
        }
        Date v2 = dateToDateFormat(val2);
        if (null == v2) {
            return 0;
        }
        long time = v2.getTime() - v1.getTime();
        return time % (365 * 24 * 60 * 60  * 1000L) / (24 * 60 * 60  * 1000L);
//        long time = val2.getTime() - val1.getTime();
//        return time % (365 * 24 * 60 * 60  * 1000L) / (24 * 60 * 60  * 1000L);
    }

    /**
     * 日期转换成固定格式
     * @param date
     * @return
     */
    private static Date dateToDateFormat(Date date) {
        return dateToDateFormat(date, null);
    }

    /**
     * 日期转换成固定格式
     * @param date
     * @param format 日期格式
     * @return
     */
    private static Date dateToDateFormat(Date date, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            String dateFormat = sdf.format(date);
            Date parse = sdf.parse(dateFormat);
            return parse;
        } catch (ParseException e) {

        }
        return null;
    }

    /**
     * 获取本周的所有日期
     * @return
     */
    public static List<String> getCurrentWeekAllDate() {
        List<String> weeks = new ArrayList<>();
        // 获取当前日期
        LocalDate currentData = LocalDate.now();
        // 获取本周的周一
        LocalDate monday = currentData.with(DayOfWeek.MONDAY);
        // 获取本周的周日
        LocalDate sunday = currentData.with(DayOfWeek.SUNDAY);

        while (!monday.isAfter(sunday)) {
            weeks.add(monday.toString());
            monday = monday.plusDays(1);
        }
        return weeks;
    }

    /**
     * 获取本月的第一天到当前的日期
     * @return
     */
    public static List<String> getCurrentDateOfMonth() {
        List<String> month = new ArrayList<>();
        // 获取当前日期
        LocalDate currentData = LocalDate.now();
        // 获取本月第一天
        LocalDate firstDayOfMonth = currentData.withDayOfMonth(1);
        while (!firstDayOfMonth.isAfter(currentData)) {
            month.add(firstDayOfMonth.toString());
            firstDayOfMonth = firstDayOfMonth.plusDays(1);
        }
        return month;
    }

    /**
     * 获取时间范围区间
     * @param date1 开始时间
     * @param date2 结束时间
     * @return
     */
    public static List<String> getDateRange(Date date1, Date date2) {
        List<String> dateRangeList = new ArrayList<>();
        if (null == date1 || null == date2) {
            return dateRangeList;
        }
        while (date2.after(date1)) {
            dateRangeList.add(DateFormatUtils.format(date1, "yyyy-MM-dd"));
            date1 = DateUtils.addDays(date1, 1);
        }
        dateRangeList.add(DateFormatUtils.format(date2, "yyyy-MM-dd"));
        return dateRangeList;
    }

    /**
     * 获取近期（含当天）天数范围
     * @param days 范围天数
     * @return
     */
    public static List<String> getInDateRange(int days) {
        List<String> dateRangeList = new ArrayList<>();
        Date currentDate = new Date();
        if (days == 0) {
            dateRangeList.add(DateFormatUtils.format(currentDate, "yyyy-MM-dd"));
        }
        Date date = DateUtils.addDays(currentDate, days);
        // 以当前日期往前算
        if (0 > days) {
            while (currentDate.after(date)) {
                date = DateUtils.addDays(date, 1);
                dateRangeList.add(DateFormatUtils.format(date, "yyyy-MM-dd"));
            }
        } else {
            // 以当前日期往后计算
            while (date.after(currentDate)) {
                dateRangeList.add(DateFormatUtils.format(currentDate, "yyyy-MM-dd"));
                currentDate = DateUtils.addDays(currentDate, 1);
            }
        }
        return dateRangeList;
    }

    public static Date getAppointDate(String dateStr, String format) {
        if (StringUtils.isBlank(format)) {
            format = DEFAULT_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {

        }
        return null;
    }





    public static void main(String[] args) {
//        System.out.println(getInDateRange(-7));
        Date date = new Date();
        Date appointDate = getAppointDate("2024-09-20", DATE_FORMAT);
        System.out.println(date);
        System.out.println(appointDate);
        System.out.println("===========================");
        System.out.println(date.after(appointDate));
        System.out.println(date.before(appointDate));
    }
}
